package com.chris.cc.user.service.wrapper;

import com.chris.cc.common.exception.InvalidArgumentException;
import com.chris.cc.user.model.dto.PermissionDto;
import com.chris.cc.user.model.dto.RoleDto;
import com.chris.cc.user.model.vo.PermissionVO;
import com.chris.cc.user.model.vo.RoleVO;
import com.chris.cc.user.service.PermissionService;
import com.chris.cc.user.service.RoleService;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Copyright (c) 2018-2025, chris All rights reserved.
 * <p>
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * <p>
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * <p>
 * Author: haoka (haokang207@126.com)
 * <p>
 * Date: 2018/8/24 10:27
 * <p>角色增删改查、授予|解除权限</p>
 * <p>权限增删改查</p>
 **/
@Service
public class PermissionServiceWrapper {

    @Autowired
    private PermissionService permissionService;
    @Autowired
    private RoleService roleService;

    /**
     * 添加权限
     *
     * @param permission
     * @throws InvalidArgumentException
     */
    public void addPermission(@NonNull PermissionDto permission) throws InvalidArgumentException {
        permissionService.add(permission);
    }

    /**
     * 查询权限列表
     *
     * @param parentId
     * @param enable
     * @param keyword
     * @param page
     * @return
     */
    public Page<PermissionVO> queryPermission(Long parentId, Boolean enable, String keyword, @NonNull Pageable page) {
        return permissionService.query(parentId, enable, keyword, page).map(PermissionVO::from);
    }

    /**
     * 更新权限
     *
     * @param permission
     * @throws InvalidArgumentException
     */
    public void updatePermission(@NonNull PermissionDto permission) throws InvalidArgumentException {
        permissionService.update(permission);
    }

    /**
     * 通过代码查询权限
     *
     * @param code
     * @return
     */
    public List<PermissionVO> getPermissionByCode(String... code) {
        return permissionService.getByCode(code).stream()
                .map(PermissionVO::from).collect(Collectors.toList());
    }

    /**
     * 获取用户的权限列表
     *
     * @param userId
     * @return
     */
    public List<PermissionVO> getPermissionByUserId(@NonNull Long userId) {
        return permissionService.getByUserId(userId).stream()
                .map(PermissionVO::from).collect(Collectors.toList());
    }

    /**
     * 添加角色
     *
     * @param role
     * @throws InvalidArgumentException
     */
    public void addRole(@NonNull RoleDto role) throws InvalidArgumentException {
        roleService.add(role);
    }

    /**
     * 查询角色列表
     *
     * @param userId  授予者用户ID
     * @param enable
     * @param keyword
     * @param page
     * @return
     */
    public Page<RoleVO> queryRole(Long userId, Boolean enable, String keyword, @NonNull Pageable page) {
        return roleService.query(userId, enable, keyword, page).map(RoleVO::from);
    }

    /**
     * 启用|禁用角色
     *
     * @param id
     * @param enable
     */
    public void toggleRole(@NonNull Long id, Boolean enable) {
        roleService.toggle(id, enable);
    }

    /**
     * 更新角色
     *
     * @param role
     * @throws InvalidArgumentException
     */
    public void updateRole(@NonNull RoleDto role) throws InvalidArgumentException {
        roleService.update(role);
    }

    /**
     * 通过代码查询角色
     *
     * @param code
     * @return
     */
    public List<RoleVO> getRoleByCode(String... code) {
        return roleService.getByCode(code).stream()
                .map(RoleVO::from).collect(Collectors.toList());
    }

    /**
     * 获取用户的角色列表
     *
     * @param userId
     * @return
     */
    public List<RoleVO> getRoleByUserId(@NonNull Long userId) {
        return roleService.getByUserId(userId).stream()
                .map(RoleVO::from).collect(Collectors.toList());
    }

    /**
     * 获取用户可以授予的角色列表
     *
     * @param userId
     * @return
     */
    public List<RoleVO> getPermittedRoles(@NonNull Long userId) {
        return roleService.getPermittedRolesByUserId(userId).stream()
                .map(RoleVO::from).collect(Collectors.toList());
    }

    /**
     * 更新角色-权限
     *
     * @param roleId
     * @param permissionIds
     */
    @Transactional
    public void updateRolePermission(@NonNull Long roleId, Long... permissionIds) {
        permissionService.updateRolePermission(roleId, permissionIds);
    }

    /**
     * 根据id获取角色
     *
     * @param id
     * @return
     */
    public RoleVO getRoleById(Long id) {
        return RoleVO.from(roleService.getById(id));
    }

    /**
     * 获取角色的权限列表
     *
     * @param roleId
     * @return
     */
    public List<PermissionVO> getPermissionByRoleId(@NotNull Long roleId) {
        return permissionService.getByRoleId(roleId).stream()
                .map(PermissionVO::from).collect(Collectors.toList());
    }

    /**
     * 获取角色可授予的角色列表
     *
     * @param roleId
     * @return
     */
    public List<RoleVO> getPermitRoleByRoleId(Long roleId) {
        return roleService.getPermittedRolesByRoleId(roleId).stream()
                .map(RoleVO::from).collect(Collectors.toList());
    }

    /**
     * 更新指定角色的可授予角色
     *
     * @param roleId
     * @param ids
     */
    @Transactional
    public void updatePermitRole(Long roleId, Long... ids) {
        roleService.updatePermitRole(roleId, ids);
    }

    /**
     * 根据id获取权限
     *
     * @param id
     * @return
     */
    public PermissionVO getPermissionById(Long id) {
        return PermissionVO.from(permissionService.getById(id));
    }

    /**
     * 删除权限
     *
     * @param id
     */
    public void deletePermission(Long id) {
        permissionService.delete(id);
    }

    public List<PermissionVO> getPermissionTree() {
        return _getPermissionTree(null);
    }

    private List<PermissionVO> _getPermissionTree(PermissionVO parent) {
        Long parentId = 0L;
        if (parent != null) {
            parentId = parent.getPermissionId();
        }
        PageRequest pageRequest = PageRequest.of(0, 999);
        List<PermissionVO> list = permissionService.query(parentId, null, null, pageRequest)
                .getContent().stream()
                .map(PermissionVO::from)
                .collect(Collectors.toList());
        for (PermissionVO p : list) {
            p.setParentId(parentId);
            p.setChildren(_getPermissionTree(p));
        }
        return list;
    }
}
